package com.enjoy.xbase.db.tools;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.enjoy.xbase.db.annotation.AnnFiled;
import com.enjoy.xbase.db.annotation.AnnTableName;

import java.lang.reflect.Field;

/**
 * Created by cxb on 2018/6/26.
 */
public class DBTools {



    /**
     * 描述：数据库更新操作
     */
    public static void update(SQLiteDatabase db,Class[] clazzs) {
        for (Class clazz : clazzs) {
            String tabName=getTabName(clazz);
            if (DBTools.tableExists(db, tabName)) {
                DBTools.updateTable(db, tabName, clazz);
            } else {
                DBTools.createTable(db, tabName, clazz);
            }
        }
    }

    /**
     * 描述：获取表名
     * @param object
     * @return
     */
    public static String getTabName(Object object){
        return getTabName(object.getClass());
    }
    /**
     * 描述：获取表名
     * @param clazz
     * @return
     */
    public static String getTabName(Class clazz){
        AnnTableName annotation = (AnnTableName) clazz.getAnnotation(AnnTableName.class);
        String tbName;
        if (annotation != null) {
            tbName = annotation.value();
        } else {
            tbName = clazz.getSimpleName().toLowerCase();
        }
        return tbName;
    }

    /**
     * 描述：获取数据主id
     * @param data
     * @return
     */
    public static int getDataId(Object data){
        Field[] fields = data.getClass().getDeclaredFields();
        for (Field _field : fields) {
            AnnFiled annFiled = _field.getAnnotation(AnnFiled.class);
            //主键不赋值
            if (annFiled != null && "id".equals(annFiled.columnName())) {
                _field.setAccessible(true);
                try {
                    return (Integer) _field.get(data);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return -1;
    }



    /**
     * 描述：判断数据库 表是否存在
     *
     * @param db
     * @param tableName
     * @return
     */
    public static boolean tableExists(SQLiteDatabase db, String tableName) {
        boolean result = false;
        if (tableName == null) {
            return false;
        }

        String sql = "select count(*) as c from sqlite_master where type ='table' and name ='" + tableName.trim() + "' ";
        Cursor cursor = db.rawQuery(sql, null);
        if (cursor.moveToNext()) {
            int count = cursor.getInt(0);
            if (count > 0) {
                result = true;
            }
        }
        cursor.close();
        return result;
    }

    /**
     * 描述：新建一个表
     *
     * @param db
     * @param clazz
     */
    public static void createTable(SQLiteDatabase db, String tabName, Class clazz) {
        Field[] fields = clazz.getDeclaredFields();
        StringBuilder sql = new StringBuilder();
        int iskey = 0;
        AnnFiled annFiled;
        for (Field field : fields) {
            annFiled = field.getAnnotation(AnnFiled.class);
            if (annFiled != null) {
                if (annFiled.columnName().equals("id")) {
                    sql.append(annFiled.columnName()).append(" ").append(annFiled.type()).append(" PRIMARY KEY AUTOINCREMENT UNIQUE ,");
                    iskey = 1;
                } else {
                    sql.append(annFiled.columnName()).append(" ").append(annFiled.type()).append(" ,");
                }
            }
        }
        if (iskey == 0) {
            sql.append("id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ,");
        }
        db.execSQL("CREATE TABLE " + tabName + " ( " + sql.substring(0, sql.length() - 1) + ");");
    }

    /**
     * 描述：更新表
     *
     * @param db
     * @param tabName
     * @param clazz
     */
    public static void updateTable(SQLiteDatabase db, String tabName, Class clazz) {
        Field[] fields = clazz.getDeclaredFields();
        AnnFiled annFiled;
        for (Field field : fields) {
            annFiled = field.getAnnotation(AnnFiled.class);
            if (annFiled != null) {
                updateTableColumn(db, tabName, annFiled.columnName(), annFiled.type());
            }
        }
    }

    /**
     * 描述：向表中新增字段
     *
     * @param db
     * @param tabName
     * @param columnName
     * @param type
     */
    private static void updateTableColumn(SQLiteDatabase db, String tabName, String columnName, String type) {
        Cursor cursor = db.rawQuery("SELECT * FROM " + tabName + " LIMIT 0", null);
        if (cursor != null) {
            if (cursor.getColumnIndex(columnName) == -1) {
                db.execSQL("ALTER TABLE " + tabName + " ADD COLUMN " + columnName + " " + type);
            }
            cursor.close();
        }
    }

    public static Object cursor2Obj(Cursor c, Class clazz) throws Exception {
        String[] columnNames = c.getColumnNames();// 字段数组
        Object obj = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for (Field _field : fields) {
            AnnFiled annFiled = _field.getAnnotation(AnnFiled.class);
            if (annFiled != null) {
                for (int j = 0; j < columnNames.length; j++) {
                    String columnName = columnNames[j];
                    if (columnName.equalsIgnoreCase(annFiled.columnName())) {// 是基本类型
                        Object val = null;
                        switch (annFiled.type()) {
                            case "INTEGER":
                                val = c.getInt(c.getColumnIndex(columnName));
                                break;
                            case "REAL":
                                val = c.getFloat(c.getColumnIndex(columnName));
                                break;
                            case "TEXT":
                                val = c.getString(c.getColumnIndex(columnName));
                                break;
                        }
                        if (val == null) {
                            j = columnNames.length;
                        } else {
                            _field.setAccessible(true);
                            _field.set(obj, val);
                            j = columnNames.length;
                        }
                    }
                }
            }
        }
        Log.i("内容", obj.toString());
        return obj;
    }


}
